package cn.lj.controller;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.lj.entity.Role;
import cn.lj.entity.RoleMenu;
import cn.lj.entity.UserRole;
import cn.lj.exception.BusinessException;
import cn.lj.response.Result;
import cn.lj.response.ResultCode;
import cn.lj.service.RoleMenuService;
import cn.lj.service.RoleService;
import cn.lj.service.UserRoleService;
import cn.lj.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 李津
 * @since 2021-05-19
 */
@RestController
@RequestMapping("/sys/role")
@Api(value = "系统角色模块",tags = "系统角色接口")
public class RoleController {
    private final RoleService roleService;

    private final RoleMenuService roleMenuService;

    private final UserService userService;

    private final UserRoleService userRoleService;

    @Autowired
    public RoleController(RoleService roleService, RoleMenuService roleMenuService, UserService userService, UserRoleService userRoleService) {
        this.roleService = roleService;
        this.roleMenuService = roleMenuService;
        this.userService = userService;
        this.userRoleService = userRoleService;
    }

    /**
     * 查询
     * @param id
     * @return
     */
    @GetMapping("/info/{id}")
    @PreAuthorize("hasAuthority('sys:role:list')")
    @ApiOperation(value = "获取单个角色信息", notes = "获取单个角色信息")
    public Result infoRole(@PathVariable(name = "id") Long id) {
        Role role = roleService.getById(id);
        if (ObjectUtil.isEmpty(role)){
            throw new BusinessException(ResultCode.ROLE_NOT_EXIST.getCode(),ResultCode.ROLE_NOT_EXIST.getMessage());
        }
        // 获取角色相关联的菜单id
        List<RoleMenu> roleMenus = roleMenuService.list(new QueryWrapper<RoleMenu>().eq("role_id", id));

        //roleMenus中menu的id单独拿出来
        List<Long> menuIds = roleMenus.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
        role.setMenuIds(menuIds);

        return Result.ok().data(role);
    }


    /**
     * 分页
     * @param name
     * @return
     */
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('sys:role:list')")
    @ApiOperation(value = "获取所有角色信息", notes = "获取所有角色信息")
    public Result listRole(@RequestParam(defaultValue = "1")Integer current, @RequestParam(defaultValue = "8")Integer size
            , String name){
        Page<Role> page = new Page<>(current,size);

        Page<Role> pageData = roleService.page(page,
                new QueryWrapper<Role>()
                        .like(StrUtil.isNotBlank(name), "name", name)
        );

        return Result.ok().data(pageData);
    }

    /**
     * 保存
     * @param role
     * @return
     */
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('sys:role:save')")
    @ApiOperation(value = "保存角色信息", notes = "保存角色信息")
    public Result saveRole(@Validated @RequestBody Role role){
        role.setCreated(LocalDateTime.now());
        roleService.save(role);

        return Result.ok().data(role);
    }


    /**
     * 修改
     * @param role
     * @return
     */
    @PostMapping("/update")
    @PreAuthorize("hasAuthority('sys:role:update')")
    @ApiOperation(value = "修改角色信息", notes = "修改角色信息")
    public Result update(@Validated @RequestBody Role role) {
        role.setUpdated(LocalDateTime.now());

        roleService.updateById(role);

        // 更新缓存
        userService.clearUserAuthorityInfoByRoleId(role.getId());

        return Result.ok();
    }

    /**
     * 删除
     * @param ids
     * @return
     */
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    @ApiOperation(value = "删除角色",notes = "删除角色")
    @Transactional
    public Result delete(@RequestBody Long[] ids) {
        roleService.removeByIds(Arrays.asList(ids));

        // 同步删除
        roleMenuService.remove(new QueryWrapper<RoleMenu>().in("role_id", (Object) ids));
        userRoleService.remove(new QueryWrapper<UserRole>().in("role_id", (Object) ids));

        // 缓存同步删除
        // 更新缓存
        Arrays.stream(ids).forEach(userService::clearUserAuthorityInfoByRoleId);

        return Result.ok();
    }

    /**
     * 更新权限
     * @param roleId
     * @param menuIds
     * @return
     */
    @PostMapping("/perm/{roleId}")
    @PreAuthorize("hasAuthority('sys:role:perm')")
    @ApiOperation(value = "更新权限",notes = "更新权限")
    @Transactional
    public Result perm(@PathVariable("roleId") Long roleId, @RequestBody Long[] menuIds) {

        List<RoleMenu> roleMenus = new ArrayList<>();

        // 增加
        Arrays.stream(menuIds).forEach(menuId->{
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setMenuId(menuId);
            roleMenu.setRoleId(roleId);

            roleMenus.add(roleMenu);
        });
        // 删除
        roleMenuService.remove(new QueryWrapper<RoleMenu>().in("role_id", roleId));

        // 最后保存
        roleMenuService.saveBatch(roleMenus);
        // 删除缓存
        userService.clearUserAuthorityInfoByRoleId(roleId);

        return Result.ok();
    }

}

